using System;
using System.Collections;
using System.IO;
using Core;
using EmbeddedWebserver.Core;
using EmbeddedWebserver.Core.Handlers.Abstract;
using EmbeddedWebserver.Core.Internal;
using EmbeddedWebserver.Core.Json;
using Microsoft.SPOT.Net.NetworkInformation;
using SolarDevices;
using SolarDevices.Configuration;

namespace SolarWeb
{
    [Serializable]
    public class Settings
    {
        public string NetBiosName;
        public string DeviceIp;
        public string GatewayIp;
        public string SubnetMask;
        public bool DHCPEnabled;
        public string NetduinoDate;
        public string ChargeController;
        public string ModbusIpAddress;
        public string ModbusPort;
        public string Inverter;
        public bool LcdEnabled;
        public bool SetClassicTime;
        public string ModbusPassword;
        public int MaxPVVoltage;
        public int PowerScale;
        public int BatteryVoltageScale;
    }
    class SettingsHandler : HandlerBase
    {
        #region Constructors

        public SettingsHandler() : base(HttpMethods.POST | HttpMethods.GET) { }

        #endregion

        #region Non-public members

        protected override void ProcessRequestWorker(HttpContext pContext)
        {
            switch (pContext.Request.Method)
            {
                case HttpMethods.GET:
                    {
                        var settings = new Settings {NetduinoDate = DateTime.Now.ToString("yyyy-MMM-dd HH:mm")};
                        var modbusConfig = new ModbusConfiguration();
                        var solarConfig = new SolarConfiguration();
                        var systemConfig = new SystemConfiguration();

                        switch (solarConfig.ChargeController)
                        {
                            case ChargeControllerType.Classic:
                                settings.ChargeController = "Classic";
                                break;
                            case ChargeControllerType.Outback:
                                settings.ChargeController = "Outback";
                                break;
                            case ChargeControllerType.TriStarTCP:
                                settings.ChargeController = "TriStarTCP";
                                break;
                            case ChargeControllerType.TriStarRTU:
                                settings.ChargeController = "TriStarRTU";
                                break;
                        }
                        switch (solarConfig.Inverter)
                        {
                            case InverterType.None:
                                settings.Inverter = "None";
                                break;
                            case InverterType.Outback:
                                settings.Inverter = "Outback";
                                break;
                        }
                        settings.NetBiosName = systemConfig.NetBiosName;
                        settings.DeviceIp = systemConfig.DeviceIp;
                        settings.GatewayIp = systemConfig.GatewayIp;
                        settings.SubnetMask = systemConfig.SubnetMask;
                        settings.DHCPEnabled = systemConfig.DHCPEnabled;
                        settings.ModbusPort = modbusConfig.ModbusSlavePort.ToString();
                        settings.ModbusIpAddress = modbusConfig.ModbusSlaveIp;
                        settings.MaxPVVoltage = solarConfig.MaxPVVoltage;
                        settings.PowerScale = solarConfig.PowerScale;
                        settings.BatteryVoltageScale = solarConfig.BatteryVoltageScale;
                        settings.LcdEnabled = systemConfig.LCDEnabled;
                        var formatter = new JsonFormatter();
                        pContext.Response.ResponseBody = formatter.ToJson(settings);
                        pContext.Response.ContentType = "application/json";

                    }
                    break;
                case HttpMethods.POST:
                    lock (this)
                    {
                        pContext.Response.ContentType = "application/json";
                        var parts = HttpRequestParser.ParseParameters(pContext.Request.RequestBody, pContext.Server);
                        var configFile = Path.Combine(Monitor.Root, Monitor.SolarConfigName);
                        var configuration = new Configuration(configFile, Monitor.Root);
                        var currentNetbiosName = configuration.SystemConfiguration.NetBiosName;
                        var nameService = NameService.GetSingleton();
                        bool networkConfigChanged = false;
                        foreach (DictionaryEntry part in parts)
                        {
                            switch (part.Key.ToString())
                            {
                                case "ModbusIpAddress":
                                    configuration.ModbusConfiguration.ModbusSlaveIp = part.Value.ToString();
                                    break;
                                case "ModbusPort":
                                    configuration.ModbusConfiguration.ModbusSlavePort = ushort.Parse(part.Value.ToString());
                                    break;
                                case "chargecontroller":
                                    if (part.Value.Equals("Classic"))
                                    {
                                        configuration.SolarSystem.ChargeController = ChargeControllerType.Classic;
                                    }
                                    else if (part.Value.Equals("Outback"))
                                    {
                                        configuration.SolarSystem.ChargeController = ChargeControllerType.Outback;
                                    }
                                    else if (part.Value.Equals("TriStarTCP"))
                                    {
                                        configuration.SolarSystem.ChargeController = ChargeControllerType.TriStarTCP;
                                    }
                                    else if (part.Value.Equals("TriStarRTU"))
                                    {
                                        configuration.SolarSystem.ChargeController = ChargeControllerType.TriStarRTU;
                                    }
                                    break;
                                case "inverter":
                                    if (part.Value.Equals("None"))
                                    {
                                        configuration.SolarSystem.Inverter = InverterType.None;
                                    }
                                    else if (part.Value.Equals("Outback"))
                                    {
                                        configuration.SolarSystem.Inverter = InverterType.Outback;
                                    }
                                    break;
                                case "lcd":
                                    configuration.SystemConfiguration.LCDEnabled = part.Value.Equals("true");
                                    break;

                                case "DHCPEnabled":
                                    var valDHCPEnabled = part.Value.Equals("true");
                                    if (configuration.SystemConfiguration.DHCPEnabled != valDHCPEnabled)
                                    {
                                        networkConfigChanged = true;
                                        configuration.SystemConfiguration.DHCPEnabled = valDHCPEnabled;
                                    }
                                    break;
                                case "DeviceIp":
                                    var valDeviceIp = part.Value.ToString();
                                    if (configuration.SystemConfiguration.DeviceIp.CompareTo(valDeviceIp) != 0)
                                    {
                                        networkConfigChanged = true;
                                        configuration.SystemConfiguration.DeviceIp = valDeviceIp;
                                    }
                                    break;
                                case "GatewayIp":
                                    var valGatewayIp = part.Value.ToString();
                                    if (configuration.SystemConfiguration.GatewayIp.CompareTo(valGatewayIp) != 0)
                                    {
                                        networkConfigChanged = true;
                                        configuration.SystemConfiguration.GatewayIp = valGatewayIp;
                                    }
                                    break;
                                case "SubnetMask":
                                    var valSubnetMask = part.Value.ToString();
                                    if (configuration.SystemConfiguration.SubnetMask.CompareTo(valSubnetMask) != 0)
                                    {
                                        networkConfigChanged = true;
                                        configuration.SystemConfiguration.SubnetMask = valSubnetMask;
                                    }
                                    break;
                                case "NetBiosName":
                                    var valNetBiosName = part.Value.ToString();
                                    if (currentNetbiosName.CompareTo(valNetBiosName) != 0)
                                    {
                                        networkConfigChanged = true;
                                        configuration.SystemConfiguration.NetBiosName = valNetBiosName;
                                    }
                                    break;
                                case "maxPVVoltage":
                                    configuration.SolarSystem.MaxPVVoltage = int.Parse(part.Value.ToString());
                                    break;
                                case "batteryVoltageScale":
                                    configuration.SolarSystem.BatteryVoltageScale = int.Parse(part.Value.ToString());
                                    break;
                                case "powerScale":
                                    configuration.SolarSystem.PowerScale = int.Parse(part.Value.ToString());
                                    break;
                            }
                        }
                        configuration.SaveConfiguration();
#if !DEBUG
                        if (networkConfigChanged)
                        {
                            try
                            {
                                DebugLogger.TryLog("Removing Netbios name: " + currentNetbiosName);
                                nameService.RemoveName(currentNetbiosName, NameService.NameType.Unique, NameService.MsSuffix.Default);
                            }
                            catch (Exception ex)
                            {
                                DebugLogger.TryLog(ex);
                            }

                        }
#endif
                    }
                    break;
            }
        }

        #endregion


    }
}